package dao;

/**
 *
 * @author yakimovich
 */
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.DriverConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

/**
 *
 * @author Yana
 */
public class AbstractJdbcDao {

    private static DataSource dataSource;
    protected Connection connection;
    protected String driverName;
    protected String uri;
    protected String username;
    protected String password;
    protected String settings;

    /**
     * Constructor by default
     */
    public AbstractJdbcDao() {
        this.settings = "db.properties";
    }

    public AbstractJdbcDao(String setting) {
        this.settings = setting;
    }
    /**
     * Create logger.
     */
    private static org.apache.commons.logging.Log logger 
            = LogFactory.getLog(AbstractJdbcDao.class);

    /**
     * Create connection.
     *
     * @return Connection with DB
     */
    public Connection createConnection() {

        try {
            if (dataSource == null) {
                dataSource = getDataSource();
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }

        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            logger.error(this, e);
            throw new IllegalStateException(e);
        }
        return connection;
    }

    /**
     * Create DataSource with the specified parameters.
     *
     * @return object of class DataSource
     *
     */
    private DataSource getDataSource() {
        setConnSettings(settings);
        
//        driverName = "org.h2.Driver";
//        uri = "jdbc:h2:d:/servlets";
//        username = "sa";
//        password = "";
        
        Properties prop = new Properties();
        prop.setProperty("user", username);
        prop.setProperty("password", password);

        Driver driver = null;
        try {
            driver = (Driver) Class.forName(driverName)
                    .newInstance();
        } catch (Exception e) {
            logger.error(this, e);
            throw new IllegalStateException(e);
        } 

        PoolableConnectionFactory factory = new PoolableConnectionFactory(
                new DriverConnectionFactory(driver, uri, prop),
                new GenericObjectPool(null),
                null, "SELECT 1", false, true);
        DataSource src = new PoolingDataSource(factory.getPool());
        return src;
    }

    protected void setConnSettings(String settings) {

        InputStream inputStream = this.getClass().getClassLoader()
                .getResourceAsStream(settings);
        Properties prop = new Properties();
        // load a properties file
        try {
            prop.load(inputStream);
        } catch (IOException e) {
            logger.error(this, e);
            throw new RuntimeException(
                    "A property file is not found");
        }
        // Read from properties file
        driverName = prop.getProperty("driverName");
        uri = prop.getProperty("uri");
        username = prop.getProperty("username");
        password = prop.getProperty("password");
    }
}
